package com.zenithmind.mall.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zenithmind.common.context.UserContext;
import com.zenithmind.common.exception.BusinessException;
import com.zenithmind.common.result.PageResult;
import com.zenithmind.mall.mapper.ProductMapper;
import com.zenithmind.mall.pojo.dto.ProductDTO;
import com.zenithmind.mall.pojo.entity.Product;
import com.zenithmind.mall.pojo.query.ProductQuery;
import com.zenithmind.mall.pojo.vo.ProductVO;
import com.zenithmind.mall.service.ProductService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 商品服务实现类
 * 
 * @author ZenithMind Team
 * @since 2025-06-09
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {

    private final ProductMapper productMapper;
    private final ObjectMapper objectMapper;

    @Override
    public PageResult<ProductVO> getProductPage(ProductQuery query) {
        Page<Product> page = query.toPage();

        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Product::getIsDeleted, 0)
               .like(StringUtils.hasText(query.getName()), Product::getName, query.getName())
               .eq(StringUtils.hasText(query.getCategoryId()), Product::getCategoryId, query.getCategoryId())
               .eq(StringUtils.hasText(query.getBrand()), Product::getBrand, query.getBrand())
               .eq(query.getStatus() != null, Product::getStatus, query.getStatus())
               .eq(query.getIsRecommend() != null, Product::getIsRecommend, query.getIsRecommend())
               .eq(query.getIsNew() != null, Product::getIsNew, query.getIsNew())
               .eq(query.getIsHot() != null, Product::getIsHot, query.getIsHot())
               .ge(query.getMinPrice() != null, Product::getPrice, query.getMinPrice())
               .le(query.getMaxPrice() != null, Product::getPrice, query.getMaxPrice())
               .gt(query.getHasStock() != null && query.getHasStock(), Product::getStock, 0);

        // 排序
        if (StringUtils.hasText(query.getSortField())) {
            boolean isAsc = "asc".equalsIgnoreCase(query.getSortOrder());
            switch (query.getSortField()) {
                case "price":
                    wrapper.orderBy(true, isAsc, Product::getPrice);
                    break;
                case "sales":
                    wrapper.orderBy(true, isAsc, Product::getSalesCount);
                    break;
                case "time":
                    wrapper.orderBy(true, isAsc, Product::getCreateTime);
                    break;
                default:
                    wrapper.orderByDesc(Product::getCreateTime);
            }
        } else {
            wrapper.orderByDesc(Product::getCreateTime);
        }

        Page<Product> result = page(page, wrapper);

        // 转换为VO
        List<ProductVO> voList = result.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());

        return new PageResult<>(voList, result.getTotal(), result.getCurrent(), result.getSize());
    }

    @Override
    public ProductVO getProductById(String id) {
        Product product = getById(id);
        if (product == null) {
            throw new BusinessException("商品不存在");
        }

        // 异步增加浏览量
        try {
            increaseViewCount(id);
        } catch (Exception e) {
            log.warn("增加商品浏览量失败: {}", id, e);
        }

        return convertToVO(product);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createProduct(ProductDTO productDTO) {
        // 验证SKU是否重复
        if (StringUtils.hasText(productDTO.getSku())) {
            validateSku(productDTO.getSku(), null);
        }

        Product product = new Product();
        BeanUtils.copyProperties(productDTO, product);

        // 处理JSON字段
        try {
            if (productDTO.getImages() != null) {
                product.setImages(objectMapper.writeValueAsString(productDTO.getImages()));
            }
            if (productDTO.getTags() != null) {
                product.setTags(objectMapper.writeValueAsString(productDTO.getTags()));
            }
            if (productDTO.getAttributes() != null) {
                product.setAttributes(objectMapper.writeValueAsString(productDTO.getAttributes()));
            }
            if (productDTO.getSpecifications() != null) {
                product.setSpecifications(objectMapper.writeValueAsString(productDTO.getSpecifications()));
            }
        } catch (Exception e) {
            throw new BusinessException("商品信息格式错误");
        }

        // 设置默认值
        if (product.getStatus() == null) {
            product.setStatus(0); // 默认下架
        }
        if (product.getIsRecommend() == null) {
            product.setIsRecommend(0);
        }
        if (product.getIsNew() == null) {
            product.setIsNew(0);
        }
        if (product.getIsHot() == null) {
            product.setIsHot(0);
        }
        if (product.getSalesCount() == null) {
            product.setSalesCount(0);
        }
        if (product.getViewCount() == null) {
            product.setViewCount(0);
        }

        product.setCreateBy(UserContext.getUserId());

        if (!save(product)) {
            throw new BusinessException("创建商品失败");
        }

        log.info("创建商品成功: {}", product.getId());
        return product.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateProduct(String id, ProductDTO productDTO) {
        Product existProduct = getById(id);
        if (existProduct == null) {
            throw new BusinessException("商品不存在");
        }

        // 验证SKU是否重复
        if (StringUtils.hasText(productDTO.getSku())) {
            validateSku(productDTO.getSku(), id);
        }

        Product product = new Product();
        BeanUtils.copyProperties(productDTO, product);
        product.setId(id);

        // 处理JSON字段
        try {
            if (productDTO.getImages() != null) {
                product.setImages(objectMapper.writeValueAsString(productDTO.getImages()));
            }
            if (productDTO.getTags() != null) {
                product.setTags(objectMapper.writeValueAsString(productDTO.getTags()));
            }
            if (productDTO.getAttributes() != null) {
                product.setAttributes(objectMapper.writeValueAsString(productDTO.getAttributes()));
            }
            if (productDTO.getSpecifications() != null) {
                product.setSpecifications(objectMapper.writeValueAsString(productDTO.getSpecifications()));
            }
        } catch (Exception e) {
            throw new BusinessException("商品信息格式错误");
        }

        product.setUpdateBy(UserContext.getUserId());

        boolean result = updateById(product);
        if (result) {
            log.info("更新商品成功: {}", id);
        }

        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteProduct(String id) {
        Product product = getById(id);
        if (product == null) {
            throw new BusinessException("商品不存在");
        }
        
        // 检查是否有未完成的订单
        // TODO: 实现订单检查逻辑
        
        boolean result = removeById(id);
        if (result) {
            log.info("删除商品成功: {}", id);
        }
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteProducts(List<String> ids) {
        // 批量检查商品是否存在
        List<Product> products = listByIds(ids);
        if (products.size() != ids.size()) {
            throw new BusinessException("部分商品不存在");
        }
        
        // TODO: 批量检查是否有未完成的订单
        
        boolean result = removeByIds(ids);
        if (result) {
            log.info("批量删除商品成功: {}", ids);
        }
        
        return result;
    }

    @Override
    public Boolean onShelf(String id) {
        return updateProductStatus(id, 1);
    }

    @Override
    public Boolean offShelf(String id) {
        return updateProductStatus(id, 0);
    }

    @Override
    public List<ProductVO> getRecommendProducts(Integer limit) {
        if (limit == null || limit <= 0) {
            limit = 10;
        }

        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Product::getIsDeleted, 0)
               .eq(Product::getStatus, 1)
               .eq(Product::getIsRecommend, 1)
               .orderByDesc(Product::getCreateTime)
               .last("LIMIT " + limit);

        List<Product> products = list(wrapper);
        return products.stream().map(this::convertToVO).collect(Collectors.toList());
    }

    @Override
    public List<ProductVO> getHotProducts(Integer limit) {
        if (limit == null || limit <= 0) {
            limit = 10;
        }

        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Product::getIsDeleted, 0)
               .eq(Product::getStatus, 1)
               .eq(Product::getIsHot, 1)
               .orderByDesc(Product::getSalesCount)
               .last("LIMIT " + limit);

        List<Product> products = list(wrapper);
        return products.stream().map(this::convertToVO).collect(Collectors.toList());
    }

    @Override
    public List<ProductVO> getNewProducts(Integer limit) {
        if (limit == null || limit <= 0) {
            limit = 10;
        }

        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Product::getIsDeleted, 0)
               .eq(Product::getStatus, 1)
               .eq(Product::getIsNew, 1)
               .orderByDesc(Product::getCreateTime)
               .last("LIMIT " + limit);

        List<Product> products = list(wrapper);
        return products.stream().map(this::convertToVO).collect(Collectors.toList());
    }

    @Override
    public void increaseViewCount(String id) {
        LambdaUpdateWrapper<Product> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(Product::getId, id)
               .setSql("view_count = view_count + 1");
        update(wrapper);
    }

    @Override
    public Boolean checkStock(String id, Integer quantity) {
        Product product = getById(id);
        return product != null && product.getStatus() == 1 && product.getStock() >= quantity;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean decreaseStock(String id, Integer quantity) {
        LambdaUpdateWrapper<Product> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(Product::getId, id)
               .ge(Product::getStock, quantity)
               .setSql("stock = stock - " + quantity);

        boolean result = update(wrapper);
        if (!result) {
            throw new BusinessException("库存不足");
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean increaseStock(String id, Integer quantity) {
        LambdaUpdateWrapper<Product> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(Product::getId, id)
               .setSql("stock = stock + " + quantity);
        return update(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean increaseSalesCount(String id, Integer quantity) {
        LambdaUpdateWrapper<Product> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(Product::getId, id)
               .setSql("sales_count = sales_count + " + quantity);
        return update(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateProductStatus(String id, String status) {
        log.info("更新商品状态: {} -> {}", id, status);

        // 根据状态字符串设置状态值
        Integer statusValue = switch (status.toUpperCase()) {
            case "OFF_SALE", "DRAFT" -> 0;
            case "ON_SALE", "PUBLISHED" -> 1;
            case "PRE_SALE" -> 2;
            default -> throw new BusinessException("无效的状态值: " + status);
        };

        return updateProductStatus(id, statusValue);
    }

    /**
     * 更新商品状态
     */
    private Boolean updateProductStatus(String id, Integer status) {
        Product product = getById(id);
        if (product == null) {
            throw new BusinessException("商品不存在");
        }
        
        product.setStatus(status);
        product.setUpdateBy(UserContext.getUserId());
        
        boolean result = updateById(product);
        if (result) {
            log.info("更新商品状态成功: {} -> {}", id, status);
        }
        
        return result;
    }

    /**
     * 验证SKU是否重复
     */
    private void validateSku(String sku, String excludeId) {
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Product::getSku, sku)
               .eq(Product::getIsDeleted, 0)
               .ne(StringUtils.hasText(excludeId), Product::getId, excludeId);

        if (count(wrapper) > 0) {
            throw new BusinessException("SKU已存在");
        }
    }

    /**
     * 转换为VO
     */
    private ProductVO convertToVO(Product product) {
        ProductVO vo = new ProductVO();
        BeanUtils.copyProperties(product, vo);

        // 处理状态文本
        switch (product.getStatus()) {
            case 0:
                vo.setStatusText("下架");
                break;
            case 1:
                vo.setStatusText("上架");
                break;
            case 2:
                vo.setStatusText("预售");
                break;
            default:
                vo.setStatusText("未知");
        }

        // 处理JSON字段
        try {
            if (StringUtils.hasText(product.getImages())) {
                vo.setImages(objectMapper.readValue(product.getImages(), List.class));
            }
            if (StringUtils.hasText(product.getTags())) {
                vo.setTags(objectMapper.readValue(product.getTags(), List.class));
            }
        } catch (Exception e) {
            log.warn("解析商品JSON字段失败: {}", product.getId(), e);
        }

        return vo;
    }
}
